class Solution
{
public:
    long long maximumScoreAfterOperations(vector<vector<int>> &edges, vector<int> &values)
    {
        int n = values.size();
        vector<vector<int>> graph(n);
        for (auto &edge : edges)
        {
            graph[edge[0]].push_back(edge[1]);
            graph[edge[1]].push_back(edge[0]);
        }

        vector<int> parents(n, -1);
        vector<vector<int>> children(n);
        function<void(int, int)> dfs = [&](int node, int parent)
        {
            parents[node] = parent;
            for (int v : graph[node])
            {
                if (v != parent)
                {
                    children[node].push_back(v);
                    dfs(v, node);
                }
            }
        };
        dfs(0, -1);

        vector<int> degrees(n, 0);
        queue<int> q;
        for (int i = 0; i < n; i++)
        {
            degrees[i] = children[i].size();
            if (degrees[i] == 0)
            {
                q.push(i);
            }
        }
        vector<long long> dp(n, -1);
        vector<long long> treeSum(n, 0);
        while (!q.empty())
        {
            int node = q.front();
            q.pop();
            if (children[node].size() == 0)
            {
                dp[node] = values[node] == 0 ? -1 : 0;
                treeSum[node] = values[node];
            }
            else
            {
                bool allChildrenHaveDpValue = true;
                long long subDpSum = 0;
                long long subTreeSum = 0;
                for (int child : children[node])
                {
                    if (dp[child] == -1)
                    {
                        allChildrenHaveDpValue = false;
                    }
                    subDpSum += dp[child];
                    subTreeSum += treeSum[child];
                }
                treeSum[node] = subTreeSum + values[node];

                if (allChildrenHaveDpValue)
                {
                    if (values[node] != 0)
                    {
                        dp[node] = max(subTreeSum, subDpSum + values[node]);
                    }
                    else
                    {
                        dp[node] = subDpSum;
                    }
                }
                else
                {
                    dp[node] = values[node] == 0 ? -1 : subDpSum;
                }
            }
            if (parents[node] != -1)
            {
                degrees[parents[node]]--;
                if (degrees[parents[node]] == 0)
                {
                    q.push(parents[node]);
                }
            }
        }
        return dp[0];
    }
};